package com.base;

import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.*;
import com.method.DmMethod;
import com.method.KmMethod;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.util.ResourceUtils;

/**
 * 基础类
 * 
 * @author 625
 *
 */
public class Base {
	/**
	 * 资源存放路径
	 */
	public static String PATH = null;

	/**
	 * 资源存放路径
	 */
	public static String BMP_PATH = null;

	static {
		PATH=Base.class.getResource("/screen/").getPath();
		if(PATH.contains("file:")){
			PATH=PATH.substring(6,PATH.length());
		}else{
			PATH=PATH.substring(1,PATH.length());
		}

		BMP_PATH=Base.class.getResource("/bmp/").getPath();
		if(BMP_PATH.contains("file:")){
			BMP_PATH=BMP_PATH.substring(6,BMP_PATH.length());
		}else {
			BMP_PATH = BMP_PATH.substring(1, BMP_PATH.length());
		}


	}



	/**
	 * 资源缓存路径
	 */
	private static Map<String, String> bmpMap = new ConcurrentHashMap<>();

	/**
	 * 大漠对象
	 */
	private static ThreadLocal<Com<DmMethod>> dmMap = new ThreadLocal<>();

	/**
	 * 键鼠对象
	 */
	private static ThreadLocal<Com<KmMethod>> kmMap = new ThreadLocal<>();

	/**
	 * 操作区域
	 */
	private static Local local = new Local(1920, 1080);

	/**
	 * 设置工作区域
	 * 
	 * @param x
	 * @param y
	 */
	public static void setWorkArea(int x, int y) {
		local = new Local(x, y);
	}

	/**
	 * 获取dm
	 * 
	 * @return
	 */
	private static Com<DmMethod> getDm() {
		Com<DmMethod> com = dmMap.get();
		if (com == null) {
			com = new Dm();
			dmMap.set(com);
		}
		return com;
	}

	/**
	 * 获取键鼠
	 * 
	 * @return
	 */
	private static Com<KmMethod> getKm() {
		Com<KmMethod> com = kmMap.get();
		if (com == null) {
			com = new Km();
			String open = com.call(KmMethod.OpenDevice);
			System.out.println("open device："+open);
			kmMap.set(com);
		}
		return com;
	}

	/**
	 * 随机休眠
	 * 
	 * @param secend
	 */
	public static void sleeps(double secend) {
		try {
			if (secend != 0) {
				TimeUnit.MILLISECONDS.sleep((int) secend * 1000);
			} else {
				TimeUnit.MILLISECONDS.sleep(1000);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}


	public static Local FreePic(String resource) {

		String call = getDm().call(DmMethod.FreePic, resource);
		if (call.contains("0")) {
			return null;
		}

		return null;

	}



	/**
	 * 找一个图
	 * 
	 * @param resource
	 *            资源文件
	 * @param x
	 *            找图范围x
	 * @param y
	 *            找图范围y
	 * @return
	 */
	public static Local findPic(String resource) {
		String path = getBmp(resource);
		String call = getDm().call(DmMethod.FindPicE, 0, 0, local.getX(), local.getY(), path, "000000", 0.7, 0);
		if (call.contains("-1")) {
			return null;
		}
		String[] split = call.split("\\|");
		return new Local(split[1], split[2]);
	}

      static 	int  i=0;

	public static Local findPicList(List<String> resource) {
		//依次执行
		if(resource.size()==0){
			return null;
		}

		//判断素材路径是否有图，如果没有，则生成图片。

		StringBuffer sb=new StringBuffer();


		resource.forEach(item->{
			if(StringUtils.isBlank(item)){
				return;
			}
			String img=getBmp(item);

			sb.append(img+"|");


		});

		if(sb.length()<1){
			return null;
		}

		//大漠无法读取到jar包内的文件，此处讲jar包内的文件复制一份到jar包运行路径。
		//然后使用新的路径传递给大漠调用。


		i++;

		String call = getDm().call(DmMethod.FindPicE, 0, 0, local.getX(), local.getY(), sb.substring(0,sb.length()-1), "000000", 0.75, 0);

		if(i>=5){
			FreePic(sb.substring(0,sb.length()-1));
		}


		if (call.contains("-1")) {
			return null;
		}
		String[] split = call.split("\\|");



		return new Local(split[1], split[2]);
	}



	/**
	 * 找多个图
	 * 
	 * @param resource
	 *            资源文件
	 * @param x
	 *            找图范围x
	 * @param y
	 *            找图范围y
	 * @return
	 */
	public static List<Local> findPics(String resource) {
		String path = getBmp(resource);
		System.out.println("find pic ----->"+path);
		String call = getDm().call(DmMethod.FindPicEx, 0, 0, local.getX(), local.getY(), path, "000000",
				1.0, 0);
		if (StringUtils.isBlank(call)) {
			return null;
		}
		String[] split = call.split("\\|");
		List<Local> locals = new ArrayList<>();
		for (String localStrs : split) {
			String[] localStr = localStrs.split(",");
			locals.add(new Local(localStr[1], localStr[2]));
		}
		return locals;
	}

	/**
	 * 图片转为24位Bmp
	 * 
	 * @param sourcePic
	 *            图片名称，请放在screen下面
	 * @return 生成的路径
	 */
	private static String ImageToBmp(String sourcePic) {

		//此处的路径无法被正常读取，讲路径的文件写入到项目当前文件夹，创造一个文件夹
		//创建一个新的文件路径。
		String path=getPath()+"resources/";
		isChartPathExist(path);

		String pathmbp=getPath()+"resources/mbp/";
		isChartPathExist(pathmbp);

		String targetPath = pathmbp  + sourcePic.substring(0, sourcePic.indexOf(".")) + ".bmp";

		//外部文件夹没有文件，则将文件写入到外部文件之中。
		File file = new File(path+sourcePic);
		if (!file.exists()) {
			Resource[] resources =null;
			try {
				// TODO 加载当前项目classpath下META-INF/folder及其子文件夹中的所有文件
				resources = new PathMatchingResourcePatternResolver().getResources(ResourceUtils.CLASSPATH_URL_PREFIX + "screen/*.png");


				//循环将文件写出到特定路径
				for (int i = 0; i < resources.length; i++) {


					InputStream inputStream =resources[i].getInputStream();

					String outPath=path+""+resources[i].getFilename();
					OutputStream outputStream = new FileOutputStream(outPath);



					int n =0;
					while((n=inputStream.read())!=-1) {//读出并写入
						outputStream.write(n);
					}
					inputStream.close();
					outputStream.close();


				}
			}catch (Exception e){
				e.printStackTrace();
			}

		}




		//判断bmp文件是否有了。如果没有，则创建
		 file = new File(targetPath);
		if (!file.exists()) {
			System.out.println("create bmp img...");
			getDm().call(DmMethod.ImageToBmp, path+sourcePic, targetPath);
		}
		;
		return targetPath;
	}


	public static String getPath()
	{
		String path = Base.class.getProtectionDomain().getCodeSource().getLocation().getPath();
		if(System.getProperty("os.name").contains("dows"))
		{
			path = path.substring(1,path.length());
		}
		if(path.contains("jar"))
		{
			path = path.substring(0,path.lastIndexOf("."));
			return path.substring(0,path.lastIndexOf("/"));
		}
		return path.replace("target/classes/", "");
	}


	private static void isChartPathExist(String dirPath) {
		File file = new File(dirPath);
		if (!file.exists()) {
			file.mkdirs();
		}
	}



	/**
	 * 获取24位Bmp图片
	 * 
	 * @param pic
	 *            普通的截图文件
	 */
	private static String getBmp(String pic) {
		String bmp = bmpMap.get(pic);
		if (bmp == null) {
			bmp = ImageToBmp(pic);
			bmpMap.put(pic, bmp);
		}
		return bmp;
	}

	/**
	 * 移动到指定坐标
	 * 
	 * @param x
	 * @param y
	 */
	public static String moveTo(int x, int y) {
		if (Com.type == 1) {
			return getKm().call(KmMethod.MoveTo, x, y);
		}
		return  getDm().call(DmMethod.MoveTo, x, y);
	}

	/**
	 * 相对移动鼠标
	 * 
	 * @param x
	 * @param y
	 */
	public static void moveToR(int x, int y) {
		if (Com.type == 1) {
			getKm().call(KmMethod.MoveToR, x, y);
			return;
		}
		getDm().call(DmMethod.MoveR, x, y);
	}

	/**
	 * 移动到指定的资源
	 * 
	 * @param pic
	 *            资源
	 * @param fix
	 *            修正的坐标
	 */
	public static void moveToPic(String pic, int... fix) {
		int fixX = 0;
		int fixY = 0;
		if (fix != null && fix.length > 0) {
			fixX = fix[0];
			fixY = fix[1];
		}

		//批量寻找特定素材文件夹里面的素材，如果有则购买。
		Local local = null;
		do {
			local = findPic(pic);
			System.out.println("move to pic------>" + pic + " " + local);
			sleeps(1);
		} while (
				local == null
		);
		moveTo(local.getX() + fixX, local.getY() + fixY);
	}

	/**
	 * 左键单击
	 */
	public static void leftClick() {
		if (Com.type == 1) {
			getKm().call(KmMethod.LeftClick, 1);
			return;
		}
		getDm().call(DmMethod.LeftClick);
	}

	/**
	 * 左键长安下
	 */
	public static void leftDown() {
		if (Com.type == 1) {
			getKm().call(KmMethod.LeftDown);
			return;
		}
		getDm().call(DmMethod.LeftDown);
	}

	/**
	 * 左键弹起
	 */
	public static void leftUp() {
		if (Com.type == 1) {
			getKm().call(KmMethod.LeftUp);
			return;
		}
		getDm().call(DmMethod.LeftUp);
	}

	/**
	 * 左键双击
	 */
	public static void leftDoubleClick() {
		if (Com.type == 1) {
			getKm().call(KmMethod.LeftDoubleClick, 1);
			return;
		}
		getDm().call(DmMethod.LeftDoubleClick);
		leftUp();
	}

	/**
	 * 左键单击，如果找到图则停止单击
	 * 
	 * @param pic
	 *            图片
	 * @param time
	 *            间隔单击事件
	 */
	public static void leftClicksIfFindPicStop(String pic, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		Local local = null;
		do {
			leftClick();
			System.out.println("left click ----> find " + pic + " stop ");
			local = findPic(pic);
			sleeps(time);
		} while (local == null);
	}

	/**
	 * 左键单击，如果没找到图则停止单击
	 * 
	 * @param pic
	 *            图片
	 * @param time
	 *            间隔单击事件
	 */
	public static void leftClicksIfNotFindPicStop(String pic, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		Local local = null;
		do {
			leftClick();
			sleeps(time);
			local = findPic(pic);
		} while (local != null);
	}

	/**
	 * 左键双击，如果找到图则停止单击
	 * 
	 * @param pic
	 *            图片
	 * @param time
	 *            间隔单击事件
	 */
	public static void leftDoubleClicksIfFindPicStop(String pic, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		Local local = null;
		do {
			leftDoubleClick();
			sleeps(time);
			local = findPic(pic);
		} while (local == null);
	}

	/**
	 * 左键双击，如果没找到图则停止单击
	 * 
	 * @param pic
	 *            图片
	 * @param time
	 *            间隔单击事件
	 */
	public static void leftDoubleClicksIfNotFindPicStop(String pic, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		Local local = null;
		do {
			leftDoubleClick();
			sleeps(time);
			local = findPic(pic);
		} while (local != null);
	}

	/**
	 * 右键单击
	 */
	public static void rightClick() {
		if (Com.type == 1) {
			getKm().call(KmMethod.RightClick, 1);
			return;
		}
		getDm().call(DmMethod.RightClick);
	}

	/**
	 * 右键长按下
	 */
	public static void rightDown() {
		if (Com.type == 1) {
			getKm().call(KmMethod.RightDown);
			return;
		}
		getDm().call(DmMethod.RightDown);
	}

	/**
	 * 右键弹起
	 */
	public static void rightUp() {
		if (Com.type == 1) {
			getKm().call(KmMethod.RightUp);
			return;
		}
		getDm().call(DmMethod.RightUp);
	}

	/**
	 * 右键双击
	 */
	public static void rightDoubleClick() {
		if (Com.type == 1) {
			getKm().call(KmMethod.RightDoubleClick, 1);
			return;
		}
		getDm().call(DmMethod.RightClick);
		sleeps(0.05);
		getDm().call(DmMethod.RightClick);
		rightUp();
	}

	/**
	 * 右键单击，如果找到图则停止单击
	 * 
	 * @param pic
	 *            图片
	 * @param time
	 *            间隔单击事件
	 */
	public static void rightClicksIfFindPicStop(String pic, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		Local local = null;
		do {
			rightClick();
			sleeps(time);
			local = findPic(pic);
			System.out.println("right click------> " + pic);
		} while (local == null);
	}

	/**
	 * 右键单击，如果没找到图则停止单击
	 * 
	 * @param pic
	 *            图片
	 * @param time
	 *            间隔单击事件
	 */
	public static void rightClicksIfNotFindPicStop(String pic, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		Local local = null;
		do {
			rightClick();
			sleeps(time);
			local = findPic(pic);
		} while (local != null);
	}

	/**
	 * 右键双击，如果找到图则停止单击
	 * 
	 * @param pic
	 *            图片
	 * @param time
	 *            间隔单击事件
	 */
	public static void rightDoubleClicksIfFindPicStop(String pic, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		Local local = null;
		do {
			rightDoubleClick();
			sleeps(time);
			local = findPic(pic);
		} while (local == null);
	}

	/**
	 * 右键双击，如果没找到图则停止单击
	 * 
	 * @param pic
	 *            图片
	 * @param time
	 *            间隔单击事件
	 */
	public static void rightDoubleClicksIfNotFindPicStop(String pic, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		Local local = null;
		do {
			rightDoubleClick();
			sleeps(time);
			local = findPic(pic);
		} while (local != null);
	}

	/**
	 * 按键长按下
	 * 
	 * @param key
	 *            按下的Key
	 */
	public static void keyDown(String key) {
		if (Com.type == 1) {
			getKm().call(KmMethod.KeyDown, key);
			return;
		}
		getDm().call(DmMethod.KeyDownChar, key);
	}

	/**
	 * 按键弹起
	 * 
	 * @param key
	 *            按下的Key
	 */
	public static void keyUp(String key) {
		if (Com.type == 1) {
			getKm().call(KmMethod.KeyUp, key);
			return;
		}
		getDm().call(DmMethod.KeyUpChar, key);
	}

	/**
	 * 尝试长按下按键如果找到图片停止按下
	 * 
	 * @param key
	 *            按下的Key
	 * @param resource
	 *            图片
	 * @param time
	 */
	public static void keyDownIfFindPicUp(String key, String resource, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		int index = 0;
		Local pic = null;
		do {
			index++;
			sleeps(time);
			pic = findPic(resource);
			System.out.println("key down long " + key + "----> " + index + " times if find "+resource +" stop");
		} while (pic == null && index < 5);
		keyUp(key);
	}

	/**
	 * 尝试长按下按键如果没找到图片停止按下
	 * 
	 * @param key
	 *            按下的Key
	 * @param resource
	 *            图片
	 * @param time
	 */
	public static void keyDownIfNotFindPicUp(String key, String resource, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		int index = 0;
		Local pic = null;
		do {
			index++;
			sleeps(time);
			pic = findPic(resource);
			System.out.println("key down long " + key + "----> " + index + " times stop if not find "+resource);
		} while (pic != null && index < 5);
		keyUp(key);
	}

	/**
	 * 按键按下
	 * 
	 * @param key
	 *            按下的Key
	 */
	public static void keyPress(String key) {
		if (Com.type == 1) {
			getKm().call(KmMethod.KeyPress, key, 1);
			return;
		}
		getDm().call(DmMethod.KeyPressChar, key);
		keyUp(key);
	}

	/**
	 * 尝试按下按键如果找到图片停止按下
	 * 
	 * @param key
	 *            按下的Key
	 * @param resource
	 *            图片
	 * @param time
	 */
	public static void keyPressIfFindPicUp(String key, String resource, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		int index = 0;
		Local pic = null;
		do {
			index++;
			keyPress(key);
			sleeps(time);
			pic = findPic(resource);
			System.out.println("key press " + key + "---->" + index + "times stop if find "+resource);
		} while (pic != null && index < 5);
	}

	/**
	 * 尝试按下按键如果找到图片停止按下
	 * 
	 * @param key
	 *            按下的Key
	 * @param resource
	 *            图片
	 * @param time
	 */
	public static void keyPressIfNotFindPicUp(String key, String resource, int... times) {
		int time = 1;
		if (times != null && times.length > 0) {
			time = times[0];
		}
		int index = 0;
		Local pic = null;
		do {
			index++;
			keyPress(key);
			sleeps(time);
			pic = findPic(resource);
			System.out.println("key press " + key + "---->" + index + "times stop if not find "+resource);
		} while (pic == null && index < 5);
	}

	/**
	 * 所有按键弹起
	 * 
	 * @param key
	 *            按下的Key
	 */
	public static void keyUpAll() {
		Com<KmMethod> km = getKm();
		km.call(KmMethod.KeyUpAll);
	}

	/**
	 * 所有鼠标弹起
	 * 
	 * @param key
	 *            按下的Key
	 */
	public static void mouseUpAll() {
		Com<KmMethod> km = getKm();
		km.call(KmMethod.MouseUpAll);
	}

}
